#include "QxWorkspaceIO.hpp"

#include <QVariant>
#include <QSqlError>
#include <QSqlQuery>

class QxWorkspaceIO::QxWorkspaceIOPrivate
{
public:

  QxWorkspaceIOPrivate( QxWorkspaceIO* me ) : m_self( me ) {
  }

  void reload( const QSqlDatabase& ) {
  }

  static bool identifyTables( const QSqlDatabase& db ) {
    QStringList tables = db.tables();
    if( !tables.contains( "DB_WORKSPACE" ) && !createWorkspaceTable( db ) ) {
      return false;
    }

    return true;
  }

  static bool createWorkspaceTable( const QSqlDatabase& db ) {
    QSqlQuery query( db );
    return query.exec( "create table DB_WORKSPACE (         "
      "id                integer primary key autoincrement, "
      "workspace_name    varchar(64),                       "
      "creator           varchar(64),                       "
      "creation_time     real,                              "
      "modifier          varchar(64),                       "
      "modification_time real                               "
      ")                                                   " );
  }

  QxWorkspaceIO*            m_self;
  QString                   m_workspaceName;
};

QxWorkspaceIO::QxWorkspaceIO( const QSqlDatabase& database )
  : QxAbstractDatabaseIO( database ), _pd( new QxWorkspaceIOPrivate( this ) )
{
}

QxWorkspaceIO::~QxWorkspaceIO()
{
}

const QString& QxWorkspaceIO::workspaceName() const
{
  return _pd->m_workspaceName;
}

void QxWorkspaceIO::setWorkspaceName( const QString& workspaceName )
{
  _pd->m_workspaceName = workspaceName;
}

QxWorkspaceDefine QxWorkspaceIO::workspaceDefine() const
{
  QxWorkspaceDefine result;

  QSqlQuery query( database() );
  query.prepare( "select creator, creation_time, modifier, modification_time from DB_WORKSPACE where workspace_name=?" );
  query.addBindValue( _pd->m_workspaceName );
  if( query.exec() && query.next() ) {
    result.workspaceName    = _pd->m_workspaceName;
    result.creator          = query.value( 0 ).toString();
    result.creationTime     = query.value( 1 ).toDateTime();
    result.modifier         = query.value( 2 ).toString();
    result.modificationTime = query.value( 3 ).toDateTime();
  }

  return result;
}

void QxWorkspaceIO::setWorkspaceDefine( const QxWorkspaceDefine& workspaceDefine )
{
  QSqlQuery query( database() );
  query.prepare( "update DB_WORKSPACE set creator=?, creation_time=?, modifier=?, modification_time=?  where workspace_mame=?" );
  query.addBindValue( workspaceDefine.creator );
  query.addBindValue( workspaceDefine.creationTime );
  query.addBindValue( workspaceDefine.modifier );
  query.addBindValue( workspaceDefine.modificationTime );
  query.addBindValue( _pd->m_workspaceName );
  query.exec();
}

QVector<QxWellInfoDefine> QxWorkspaceIO::wellInfoDefines() const
{
  QVector<QxWellInfoDefine> result;

  QSqlQuery query( database() );
  query.prepare( "select well_name, x_coordinate, y_coordinate, start_depth, stop_depth, step_depth, null_value from DB_WELLINFO" );
  while( query.next() ) {
    QxWellInfoDefine wellInfoDefine;
    wellInfoDefine.wellName    = query.value( 0 ).toString();
    wellInfoDefine.location    = QPointF(query.value(1).toFloat(), query.value( 2 ).toFloat());
    wellInfoDefine.startDepth  = query.value( 3 ).toFloat();
    wellInfoDefine.stopDepth   = query.value( 4 ).toFloat();
    wellInfoDefine.stepDepth   = query.value( 5 ).toFloat();
    wellInfoDefine.nullValue   = query.value( 6 ).toFloat();
    result << wellInfoDefine;
  }

  return result;
}

bool QxWorkspaceIO::insertWellInfoDefine( const QxWellInfoDefine& wellInfoDefine )
{
  QSqlQuery query( database() );
  query.prepare( "insert into DB_WELLINFO( well_name, x_coordinate, y_coordinate, start_depth, stop_depth, step_depth, null_value ) values( ?, ?, ?, ?, ?, ?, ? )" );
  query.addBindValue( wellInfoDefine.wellName );
  query.addBindValue( wellInfoDefine.location.x() );
  query.addBindValue( wellInfoDefine.location.y() );
  query.addBindValue( wellInfoDefine.startDepth );
  query.addBindValue( wellInfoDefine.stopDepth );
  query.addBindValue( wellInfoDefine.stepDepth );
  query.addBindValue( wellInfoDefine.nullValue );

  return query.exec();
}

bool QxWorkspaceIO::removeWellInfoDefine( const QxWellInfoDefine& wellInfoDefine )
{
  QSqlQuery query( database() );
  query.prepare( "delete from DB_WELLINFO where well_name=?" );
  query.addBindValue( wellInfoDefine.wellName );
  return query.exec();
}

QStringList QxWorkspaceIO::queryWellNames() const
{
  QStringList result;

  QSqlQuery query( database() );
  query.prepare( "select well_name from DB_WELLINFO" );
  query.exec();
  while( query.next() ) {
    result << query.value( 0 ).toString();
  }

  return result;
}

void QxWorkspaceIO::createTable( const QSqlDatabase& db )
{
  QxWorkspaceIOPrivate::identifyTables( db );
}

void QxWorkspaceIO::init()
{
  if( _pd->identifyTables( database() ) ) {
    _pd->reload( database() );
  }
}
